package org.example.xsda.service;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.example.xsda.common.PageResult;
import org.example.xsda.dto.StudentDTO;
import org.example.xsda.entity.*;
import org.example.xsda.exception.BusinessException;
import org.example.xsda.mapper.*;
import org.example.xsda.util.PasswordUtil;
import org.example.xsda.vo.StudentVO;
import org.example.xsda.vo.StudentProfileVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;

/**
 * 学生服务
 */
@Slf4j
@Service
public class StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private ClassesMapper classesMapper;

    @Autowired
    private ParentStudentMapper parentStudentMapper;
    
    @Resource
    private StudentScoreMapper studentScoreMapper;
    
    @Resource
    private StudentRecordMapper studentRecordMapper;
    
    @Resource
    private ApprovalMapper approvalMapper;
    
    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private RedisService redisService;

    // 缓存key前缀
    private static final String CACHE_KEY_STUDENT = "student:";
    private static final String CACHE_KEY_STUDENT_PROFILE = "student:profile:";

    /**
     * 分页查询学生
     */
    public PageResult<StudentVO> page(Long current, Long size, String keyword, Long deptId, Long classId, Integer status) {
        Page<Student> page = new Page<>(current, size);
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(Student::getStudentNo, keyword)
                    .or().exists("SELECT 1 FROM sys_user WHERE id = student.user_id AND real_name LIKE {0}", "%" + keyword + "%"));
        }
        if (deptId != null) {
            wrapper.eq(Student::getDeptId, deptId);
        }
        if (classId != null) {
            wrapper.eq(Student::getClassId, classId);
        }
        if (status != null) {
            wrapper.eq(Student::getStatus, status);
        }
        
        Page<Student> studentPage = studentMapper.selectPage(page, wrapper);
        
        // 转换为VO
        List<StudentVO> voList = new ArrayList<>();
        for (Student student : studentPage.getRecords()) {
            StudentVO vo = convertToVO(student);
            voList.add(vo);
        }
        
        return new PageResult<>(studentPage.getTotal(), voList, studentPage.getCurrent(), studentPage.getSize());
    }

    /**
     * 获取所有学生列表（不分页，用于下拉选择）
     */
    public List<StudentVO> list() {
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Student::getStudentNo);
        List<Student> students = studentMapper.selectList(wrapper);
        
        // 转换为VO
        List<StudentVO> voList = new ArrayList<>();
        for (Student student : students) {
            StudentVO vo = convertToVO(student);
            voList.add(vo);
        }
        
        return voList;
    }

    /**
     * 获取学生详情（带缓存）
     */
    public StudentVO getById(Long id) {
        String cacheKey = CACHE_KEY_STUDENT + id;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取学生信息：id={}", id);
            return (StudentVO) cached;
        }
        
        // 缓存未命中，从数据库查询
        Student student = studentMapper.selectById(id);
        if (student == null) {
            throw new BusinessException("学生不存在");
        }
        StudentVO vo = convertToVO(student);
        
        // 存入缓存（30分钟）
        redisService.set(cacheKey, vo);
        log.debug("将学生信息存入缓存：id={}", id);
        
        return vo;
    }

    /**
     * 新增学生
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(StudentDTO dto) {
        // 检查学号是否已存在
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getStudentNo, dto.getStudentNo());
        Long count = studentMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException("学号已存在");
        }

        // 创建用户账号
        SysUser user = new SysUser();
        user.setUsername(dto.getStudentNo());
        user.setPassword(PasswordUtil.encrypt("123456")); // 默认密码
        user.setRealName(dto.getRealName());
        user.setRoleId(1L); // 学生角色ID，需要从角色表查询
        user.setPhone(dto.getPhone());
        user.setStatus(1);
        user.setNeedChangePassword(1); // 首次登录需要修改密码
        sysUserMapper.insert(user);

        // 创建学生信息
        Student student = new Student();
        BeanUtils.copyProperties(dto, student);
        student.setUserId(user.getId());
        student.setStatus(1); // 在籍
        student.setInfoCompleted(0); // 标记为未完善个人信息
        studentMapper.insert(student);
        
        // 清除相关缓存
        redisService.deleteByPattern(CACHE_KEY_STUDENT);

        log.info("新增学生成功：{}", dto.getStudentNo());
    }

    /**
     * 更新学生
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(StudentDTO dto) {
        Student student = studentMapper.selectById(dto.getId());
        if (student == null) {
            throw new BusinessException("学生不存在");
        }

        // 更新学生信息
        BeanUtils.copyProperties(dto, student);
        studentMapper.updateById(student);

        // 更新用户信息
        SysUser user = sysUserMapper.selectById(student.getUserId());
        if (user != null) {
            user.setRealName(dto.getRealName());
            user.setPhone(dto.getPhone());
            sysUserMapper.updateById(user);
        }
        
        // 清除相关缓存
        redisService.delete(CACHE_KEY_STUDENT + dto.getId());
        redisService.delete(CACHE_KEY_STUDENT_PROFILE + student.getUserId());

        log.info("更新学生成功：{}", dto.getStudentNo());
    }

    /**
     * 删除学生
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        Student student = studentMapper.selectById(id);
        if (student == null) {
            throw new BusinessException("学生不存在");
        }

        studentMapper.deleteById(id);
        
        // 清除相关缓存
        redisService.delete(CACHE_KEY_STUDENT + id);
        redisService.delete(CACHE_KEY_STUDENT_PROFILE + student.getUserId());
        
        log.info("删除学生成功：{}", student.getStudentNo());
    }

    /**
     * 转换为VO
     */
    private StudentVO convertToVO(Student student) {
        StudentVO vo = new StudentVO();
        BeanUtils.copyProperties(student, vo);

        // 查询用户信息
        if (student.getUserId() != null) {
            SysUser user = sysUserMapper.selectById(student.getUserId());
            if (user != null) {
                vo.setRealName(user.getRealName());
            }
        }

        // 查询院系信息
        if (student.getDeptId() != null) {
            Dept dept = deptMapper.selectById(student.getDeptId());
            if (dept != null) {
                vo.setDeptName(dept.getDeptName());
            }
        }

        // 查询班级信息
        if (student.getClassId() != null) {
            Classes classes = classesMapper.selectById(student.getClassId());
            if (classes != null) {
                vo.setClassName(classes.getClassName());
            }
        }

        // 设置性别文本
        if (student.getGender() != null) {
            vo.setGenderText(student.getGender() == 1 ? "男" : "女");
        }

        // 设置状态文本
        String statusText = "未知";
        if (student.getStatus() != null) {
            switch (student.getStatus()) {
                case 1:
                    statusText = "在籍";
                    break;
                case 2:
                    statusText = "休学";
                    break;
                case 3:
                    statusText = "毕业";
                    break;
                case 4:
                    statusText = "退学";
                    break;
                default:
                    statusText = "未知";
            }
        }
        vo.setStatusText(statusText);

        return vo;
    }
    
    /**
     * 获取当前学生的个人档案（带缓存）
     */
    public StudentProfileVO getMyProfile() {
        // 1. 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        
        String cacheKey = CACHE_KEY_STUDENT_PROFILE + userId;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取学生档案：userId={}", userId);
            return (StudentProfileVO) cached;
        }
        
        // 2. 根据userId查找student记录
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getUserId, userId);
        Student student = studentMapper.selectOne(wrapper);
        
        if (student == null) {
            throw new BusinessException("未找到学生信息，请联系管理员");
        }
        
        // 3. 构建VO
        StudentProfileVO profile = new StudentProfileVO();
        
        // ==== 基本信息 ====
        profile.setStudentId(student.getId());
        profile.setStudentNo(student.getStudentNo());
        profile.setGender(student.getGender());
        profile.setGenderText(student.getGender() == 1 ? "男" : "女");
        profile.setBirthday(student.getBirthday());
        
        // 计算年龄
        if (student.getBirthday() != null) {
            Period age = Period.between(student.getBirthday(), LocalDate.now());
            profile.setAge(age.getYears());
        }
        
        profile.setPhone(student.getPhone());
        profile.setAddress(student.getAddress());
        
        // ==== 学籍信息 ====
        profile.setDeptId(student.getDeptId());
        profile.setClassId(student.getClassId());
        profile.setEnrollDate(student.getEnrollDate());
        
        if (student.getEnrollDate() != null) {
            profile.setEnrollYear(student.getEnrollDate().getYear());
        }
        
        profile.setStatus(student.getStatus());
        profile.setStatusText(getStatusText(student.getStatus()));
        profile.setRemark(student.getRemark());
        
        // 院系信息
        if (student.getDeptId() != null) {
            Dept dept = deptMapper.selectById(student.getDeptId());
            if (dept != null) {
                profile.setDeptName(dept.getDeptName());
            }
        }
        
        // 班级信息
        if (student.getClassId() != null) {
            Classes classes = classesMapper.selectById(student.getClassId());
            if (classes != null) {
                profile.setClassName(classes.getClassName());
                
                // 班主任信息
                if (classes.getHeadTeacherId() != null) {
                    SysUser headTeacher = sysUserMapper.selectById(classes.getHeadTeacherId());
                    if (headTeacher != null) {
                        profile.setHeadTeacherName(headTeacher.getRealName());
                    }
                }
            }
        }
        
        // ==== 账号信息 ====
        profile.setUserId(userId);
        SysUser user = sysUserMapper.selectById(userId);
        if (user != null) {
            profile.setRealName(user.getRealName());
            profile.setAvatar(user.getAvatar()); // 头像（来自sys_user）
            profile.setUsername(user.getUsername());
            profile.setAccountStatus(user.getStatus());
            
            // 角色信息 - 查询角色表获取角色名称
            if (user.getRoleId() != null) {
                SysRole role = roleMapper.selectById(user.getRoleId());
                if (role != null) {
                    profile.setRoleName(role.getRoleName());
                }
            }
        }
        
        // 证件照（来自student表）
        profile.setIdPhoto(student.getIdPhoto());
        
        // ==== 统计信息 ====
        // 总学分和平均分
        LambdaQueryWrapper<StudentScore> scoreWrapper = new LambdaQueryWrapper<>();
        scoreWrapper.eq(StudentScore::getStudentId, student.getId());
        List<StudentScore> scores = studentScoreMapper.selectList(scoreWrapper);
        
        if (!scores.isEmpty()) {
            double totalCredits = scores.stream()
                .mapToDouble(s -> s.getCredit() != null ? s.getCredit().doubleValue() : 0.0)
                .sum();
            double avgScore = scores.stream()
                .mapToDouble(s -> s.getScore() != null ? s.getScore().doubleValue() : 0.0)
                .average()
                .orElse(0.0);
            
            profile.setTotalCredits(totalCredits);
            profile.setAverageScore(Math.round(avgScore * 100.0) / 100.0);
            profile.setCourseCount(scores.size());
        } else {
            profile.setTotalCredits(0.0);
            profile.setAverageScore(0.0);
            profile.setCourseCount(0);
        }
        
        // 档案记录数
        LambdaQueryWrapper<StudentRecord> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(StudentRecord::getStudentId, student.getId());
        Long recordCount = studentRecordMapper.selectCount(recordWrapper);
        profile.setRecordCount(recordCount.intValue());
        
        // 待审批申请数
        LambdaQueryWrapper<Approval> approvalWrapper = new LambdaQueryWrapper<>();
        approvalWrapper.eq(Approval::getStudentId, student.getId());
        approvalWrapper.eq(Approval::getStatus, 0); // 待审批
        Long pendingCount = approvalMapper.selectCount(approvalWrapper);
        profile.setPendingApprovalCount(pendingCount.intValue());
        
        // ==== 最近成绩（前5条）====
        LambdaQueryWrapper<StudentScore> recentScoreWrapper = new LambdaQueryWrapper<>();
        recentScoreWrapper.eq(StudentScore::getStudentId, student.getId());
        recentScoreWrapper.orderByDesc(StudentScore::getCreateTime);
        recentScoreWrapper.last("LIMIT 5");
        List<StudentScore> recentScores = studentScoreMapper.selectList(recentScoreWrapper);
        
        List<StudentProfileVO.RecentScore> recentScoreList = new ArrayList<>();
        for (StudentScore score : recentScores) {
            StudentProfileVO.RecentScore rs = new StudentProfileVO.RecentScore();
            rs.setCourseName(score.getCourseName());
            rs.setScore(score.getScore() != null ? score.getScore().doubleValue() : 0.0);
            rs.setCredit(score.getCredit() != null ? score.getCredit().doubleValue() : 0.0);
            rs.setSemester(score.getSemester());
            rs.setCreateTime(score.getCreateTime());
            recentScoreList.add(rs);
        }
        profile.setRecentScores(recentScoreList);
        
        // ==== 最近档案记录（前5条）====
        LambdaQueryWrapper<StudentRecord> recentRecordWrapper = new LambdaQueryWrapper<>();
        recentRecordWrapper.eq(StudentRecord::getStudentId, student.getId());
        recentRecordWrapper.orderByDesc(StudentRecord::getCreateTime);
        recentRecordWrapper.last("LIMIT 5");
        List<StudentRecord> recentRecords = studentRecordMapper.selectList(recentRecordWrapper);
        
        List<StudentProfileVO.RecentRecord> recentRecordList = new ArrayList<>();
        for (StudentRecord record : recentRecords) {
            StudentProfileVO.RecentRecord rr = new StudentProfileVO.RecentRecord();
            rr.setRecordType(getRecordTypeName(record.getRecordType()));
            rr.setContent(record.getContent());
            rr.setCreateTime(record.getCreateTime());
            recentRecordList.add(rr);
        }
        profile.setRecentRecords(recentRecordList);
        
        // 存入缓存（10分钟，档案信息变化较频繁）
        redisService.set(cacheKey, profile, 10, java.util.concurrent.TimeUnit.MINUTES);
        log.info("获取学生档案成功并缓存：studentId={}, studentNo={}", student.getId(), student.getStudentNo());
        
        return profile;
    }
    
    // ========== 私有辅助方法 ==========
    
    private String getStatusText(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 1: return "在籍";
            case 2: return "休学";
            case 3: return "毕业";
            case 4: return "退学";
            default: return "未知";
        }
    }
    
    private String getRecordTypeName(Integer recordType) {
        if (recordType == null) return "未知";
        switch (recordType) {
            case 1: return "奖惩记录";
            case 2: return "异动记录";
            default: return "其他";
        }
    }
    
    /**
     * 学生更新个人信息
     * 学生只能修改：头像、证件照、性别、出生日期、联系电话、家庭住址
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateMyProfile(org.example.xsda.dto.StudentProfileUpdateDTO dto) {
        // 1. 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 2. 根据userId查找student记录
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getUserId, userId);
        Student student = studentMapper.selectOne(wrapper);
        
        if (student == null) {
            throw new BusinessException("未找到学生信息，请联系管理员");
        }
        
        // 3. 更新sys_user表的头像
        SysUser user = sysUserMapper.selectById(userId);
        if (user != null && dto.getAvatar() != null) {
            user.setAvatar(dto.getAvatar());
            sysUserMapper.updateById(user);
            log.info("更新用户头像成功：userId={}", userId);
        }
        
        // 4. 更新student表的信息
        if (dto.getIdPhoto() != null) {
            student.setIdPhoto(dto.getIdPhoto());
        }
        if (dto.getGender() != null) {
            student.setGender(dto.getGender());
        }
        if (dto.getBirthday() != null) {
            student.setBirthday(dto.getBirthday());
        }
        if (dto.getPhone() != null) {
            student.setPhone(dto.getPhone());
        }
        if (dto.getAddress() != null) {
            student.setAddress(dto.getAddress());
        }
        
        // 5. 标记个人信息已完善（暂不标记，等绑定家长后再标记）
        // student.setInfoCompleted(1);
        
        studentMapper.updateById(student);
        
        // 清除个人档案缓存
        redisService.delete(CACHE_KEY_STUDENT_PROFILE + userId);
        redisService.delete(CACHE_KEY_STUDENT + student.getId());
        
        log.info("更新学生个人信息成功：studentId={}, userId={}", student.getId(), userId);
    }
    
    /**
     * 学生绑定家长
     * 学生填写父母信息，系统自动创建家长账号并建立关联
     */
    @Transactional(rollbackFor = Exception.class)
    public void bindParents(org.example.xsda.dto.ParentBindDTO dto) {
        // 1. 获取当前学生
        Long userId = StpUtil.getLoginIdAsLong();
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getUserId, userId);
        Student student = studentMapper.selectOne(wrapper);
        
        if (student == null) {
            throw new BusinessException("未找到学生信息");
        }
        
        // 2. 绑定父亲
        if (dto.getFatherPhone() != null && !dto.getFatherPhone().trim().isEmpty()) {
            bindParent(student.getId(), dto.getFatherName(), dto.getFatherPhone(), "父亲");
        }
        
        // 3. 绑定母亲
        if (dto.getMotherPhone() != null && !dto.getMotherPhone().trim().isEmpty()) {
            bindParent(student.getId(), dto.getMotherName(), dto.getMotherPhone(), "母亲");
        }
        
        // 4. 标记信息已完善
        student.setInfoCompleted(1);
        studentMapper.updateById(student);
        
        // 清除个人档案缓存
        redisService.delete(CACHE_KEY_STUDENT_PROFILE + userId);
        redisService.delete(CACHE_KEY_STUDENT + student.getId());
        
        log.info("学生绑定家长成功：studentId={}, userId={}", student.getId(), userId);
    }
    
    /**
     * 绑定单个家长
     */
    private void bindParent(Long studentId, String parentName, String parentPhone, String relation) {
        // 1. 查询家长账号是否已存在（通过手机号）
        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysUser::getUsername, parentPhone);
        SysUser parentUser = sysUserMapper.selectOne(userWrapper);
        
        Long parentUserId;
        
        if (parentUser == null) {
            // 2. 家长账号不存在，创建新账号
            SysUser newParent = new SysUser();
            newParent.setUsername(parentPhone);  // 用户名为手机号
            newParent.setPassword(PasswordUtil.encrypt("123456"));  // 初始密码123456
            newParent.setRealName(parentName);
            newParent.setRoleId(2L);  // 家长角色ID（需要确认）
            newParent.setPhone(parentPhone);
            newParent.setStatus(1);
            newParent.setNeedChangePassword(1);  // 首次登录需要修改密码
            sysUserMapper.insert(newParent);
            
            parentUserId = newParent.getId();
            log.info("创建家长账号：username={}, realName={}", parentPhone, parentName);
        } else {
            // 3. 家长账号已存在
            parentUserId = parentUser.getId();
            log.info("家长账号已存在：username={}, userId={}", parentPhone, parentUserId);
        }
        
        // 4. 检查关联关系是否已存在
        LambdaQueryWrapper<ParentStudent> psWrapper = new LambdaQueryWrapper<>();
        psWrapper.eq(ParentStudent::getParentId, parentUserId);
        psWrapper.eq(ParentStudent::getStudentId, studentId);
        Long count = parentStudentMapper.selectCount(psWrapper);
        
        if (count == 0) {
            // 5. 创建家长-学生关联
            ParentStudent ps = new ParentStudent();
            ps.setParentId(parentUserId);
            ps.setStudentId(studentId);
            ps.setRelation(relation);
            parentStudentMapper.insert(ps);
            
            log.info("创建家长学生关联：parentId={}, studentId={}, relation={}", 
                    parentUserId, studentId, relation);
        } else {
            log.info("家长学生关联已存在：parentId={}, studentId={}", parentUserId, studentId);
        }
    }
}

